#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>


#include "config/config.h"
#include "get_index.h"
#include "cpp.h"
#include "authentification.h"
#include "real_path.h"
#include "cgi.h"
#include "content.h"
#include "gzip.h"

#include "get_page.h"

void
get_page(int isock, requete_t req, log_client *logc)
{
  if (!req->url)
    {
      //fichier demande n'existe pas
      envoyer_code(isock, requete_not_found,logc,NOT_FOUND);
      
      if (req->methode == head)
	return;//on affiche que les entete

      int fd = open(NOT_FOUND,O_RDONLY);
      perror_and_exit_whenever(fd == -1);
      copier_fichier(isock,fd);
      close(fd);
      
      return ;
    }
  
  if (!strstr(req->url,ROOT) || strstr(req->url,PSWDFILE))
    {
      
      
      //forbidden
      envoyer_code(isock,requete_forbidden,logc,FORBIDDEN);
      if (req->methode == head)
	return;//on affiche que les entete

      int fd = open(FORBIDDEN,O_RDONLY);
      perror_and_exit_whenever(fd == -1);
      copier_fichier(isock,fd);
      close(fd);
      
      return;
    }
    

  
  if(strcmp(req->url+(strlen(req->url)-strlen("/auth")),"/auth")==0 || strstr(req->url,"/auth/"))
    {
      if (!authorization(req->Authorization))
	{
	  logc->code_retour = malloc(sizeof(char)*(strlen(requete_unauthorized)+1));
	  strcpy(logc->code_retour,requete_unauthorized);
	  envoyer_chaine(isock,requete_unauthorized);
	  envoyer_chaine(isock,authenticate);
	  envoyer_chaine(isock,content);
	  envoyer_chaine(isock,content_html);
	  envoyer_chaine(isock,"\n");

	  int fd = open(UNAUTHORIZED,O_RDONLY);
	  perror_and_exit_whenever(fd == -1);
	  copier_fichier(isock,fd);
	  close(fd);

	  return;
	}
    }



  
  if (strstr(req->url,"/cgi-bin/") && !strstr(req->url,".html"))
    {
      logc->code_retour = malloc(sizeof(char)*(strlen(requete_ok)+1));
      strcpy(logc->code_retour,requete_ok);
      envoyer_chaine(isock,requete_ok);


      if (req->methode == head)
	{
	  envoyer_chaine(isock,content);
	  envoyer_chaine(isock,content_html);
	  envoyer_chaine(isock,"\n");
	  return;
	}

      cgi(req->url,isock);
      return;
    }

  if (est_dossier(req->url))
    {
      
      

      char *existe_index = index_existe(req->url);
	
      if (existe_index == NULL)
	{
	  envoyer_code(isock,requete_ok,logc,req->url);
	  if (req->methode == head)
	    return;

	  char *path_cpy = strstr(req->url,ROOT);
	  char *index =generer_index(path_cpy+strlen(ROOT),"index");
	    
	  if (index != NULL)
	    {
	      int r = write(isock,index,sizeof(char)*(strlen(index)+1));
	      perror_and_exit_whenever(r <= 0);
	      envoyer_chaine(isock,"\n\n");
		
	      free(index);
	      index = NULL;
	    }
	    
	  else
	    perror_and_exit_whenever(1);
	    
	}
      else
	{
	  char *new_path = malloc(sizeof(char)*(strlen(req->url)+strlen(existe_index)+2));
	  //2 car on rajoute aussi '/'
	    
	  strcpy(new_path,req->url);
	  strcat(new_path,"/");
	  strcat(new_path,existe_index);
	    
	  free(existe_index);
	    
	  if (req->Accept_Encoding && 
	      strstr(req->Accept_Encoding,"gzip"))
	    {
	      envoyer_chaine(isock,requete_ok);
	      
	      envoyer_chaine(isock,content);
	      envoyer_chaine(isock,get_content_type(new_path));
	      envoyer_chaine(isock,acceptgzip);
	      envoyer_chaine(isock,"\n");
	      
	      
	      if (req->methode == head)
		{
		  free(new_path);
		  return;
		}
	      gzip(new_path, isock);
	    }
	  else
	    {
	      envoyer_code(isock,requete_ok,logc,req->url);
	      if (req->methode == head)
		{
		  free(new_path);
		  return;
		}
	      int fdindex = open(new_path,O_RDONLY);
	      perror_and_exit_whenever(fdindex == -1);
	      copier_fichier(isock,fdindex);
	      close(fdindex);
	      
	    }
	  free(new_path);
	}
    }
  else //on reclame un fichier
    {
      if (strstr(req->url,"/cpp/") && strcmp(req->url+(strlen(req->url)-strlen(".cpp")),".cpp") == 0)
	{
	  envoyer_code(isock,requete_ok,logc,req->url);
	  if (req->methode == head)
	    return;//on affiche que les entete
	  preprocesser_cpp(req->url,isock);
	}
      else
	{

	  
	  if (req->Accept_Encoding && 
	      strstr(req->Accept_Encoding,"gzip"))
	    {
	      envoyer_chaine(isock,requete_ok);
	      
	      envoyer_chaine(isock,content);
	      envoyer_chaine(isock,get_content_type(req->url));
	      envoyer_chaine(isock,acceptgzip);
	      envoyer_chaine(isock,"\n");
	      

	      if (req->methode == head)
		return;//on affiche que les entete
	      
	      gzip(req->url, isock);
	      
	    }
	  else
	    {
	      envoyer_code(isock,requete_ok,logc,req->url);
	      if (req->methode == head)
		return;//on affiche que les entete
	      
	      int fd = open(req->url,O_RDONLY);
	      perror_and_exit_whenever(fd == -1);
	      copier_fichier(isock,fd);
	      close(fd);
	    }
	      
	}
    }
    
}
